﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Collections;

namespace MyCalc
{
    class Program
    {
        static void Main(string[] args)
        {
            string str = "";//исходное выражение
            string boof1 = "", boof2 = "";//Буферные строки для цифер
            string strAction = "";//строка в которую погружаем действие sin cos......
            char sing = ' ';//какоц знак
            bool flagDigit = true;//для определение 1 и 2 цифры
            bool flagA = false;//если сохраняем какое-то число число
            bool flagAction = false;//если sin cos...............
            bool flagScript = false;//если работаем с файлом script.txt
            bool flagRead = true; //достып к чтению с файла
            bool flagDog = false;
            double res = 0.0;
            int count = 0;
            double[] mas = new double[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
            List<string> myList = new List<string>();//При работе с script.txt
            //Operate op;
            Operate op;
            Console.WriteLine("Введите вырежение типа <a + b> и нажмите Enter. \nПоддержка функций: sqrt(а), cos(а°), sin(а°), exp(а), factorial(а).\nДля работы со скриптом введите <execute>.\nДля обозначение результата последнего выражения использовать символ '@'.\nДля промежуточного сохранения введите <store a1...20>.\nДля выхода введите <exit>.");
start:            Console.Write("Введите выражение -> ");
            str = Console.ReadLine();
            if (str == "")
            {
                Console.WriteLine("Вы ничего не ввели!");
                goto start;
            }
read:            if (str != "exit")
            {
                for (int i = 0; i < str.Length; i++)
                {
                    if (str[i] == ' ' || str[i] == '(' || str[i] == ')')
                    {
                    }
                    else if (flagDigit == false)
                    {
                        if (str[i] == '@')
                        {
                            boof2 = res.ToString();
                            flagDog = true;
                        }
                        else
                        {
                            boof2 += str[i];
                        }
                    }
                    else if (str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/' || str[i] == '%' || str[i] == '^')
                    {
                        sing = str[i];
                        flagDigit = false;
                    }
                    else if (flagDigit == true)
                    {
                        if (str[i] == '@')
                        {
                            boof1 = res.ToString();
                            flagDog = true;
                        }
                        else
                        {
                            boof1 += str[i];
                            if (boof1 == "store")
                            {
                                flagA = true;
                            }
                            if (boof1 == "sin" || boof1 == "cos" || boof1 == "sqrt" || boof1 == "exp" || boof1 == "factorial")
                            {
                                flagAction = true;
                                strAction = boof1;
                            }
                            if (boof1 == "execute")
                            {
                                flagScript = true;
                            }
                        }
                    }
                }
                if (flagA == true)//если сохраняем какой-то результат
                {
                    int elemSave;//№ элемента массива, куда происходит сохранение результата
                    elemSave = retNum(boof1, 'a');
                    mas[elemSave - 1] = res;
                    flagA = false;
                    Console.WriteLine("a" + elemSave + " = " + mas[elemSave - 1]);
                }
                else if (flagAction == true)//если sin cos...............
                {
                    int n1;
                    switch (strAction)
                    {
                        case "sin":
                            if (flagDog == true)
                            {
                                n1 = Convert.ToInt32(boof1);
                                flagDog = false;
                            }
                            else
                            {
                                n1 = retNum(boof1, 'n');
                            }
                            op = new Operate(strAction, n1);
                            res = op.resultAction();
                            Console.WriteLine("Результат -> " + res);
                            break;
                        case "cos":
                            if (flagDog == true)
                            {
                                n1 = Convert.ToInt32(boof1);
                                flagDog = false;
                            }
                            else
                            {
                                n1 = retNum(boof1, 's');
                            }
                            op = new Operate(strAction, n1);
                            res = op.resultAction();
                            Console.WriteLine("Результат -> " + res);
                            break;
                        case "sqrt":
                            if (flagDog == true)
                            {
                                n1 = Convert.ToInt32(boof1);
                                flagDog = false;
                            }
                            else
                            {
                                n1 = retNum(boof1, 't');
                            }
                            op = new Operate(strAction, n1);
                            res = op.resultAction();
                            Console.WriteLine("Результат -> " + res);
                            break;
                        case "exp":
                            if (flagDog == true)
                            {
                                n1 = Convert.ToInt32(boof1);
                                flagDog = false;
                            }
                            else
                            {
                                n1 = retNum(boof1, 'p');
                            }
                            op = new Operate(strAction, n1);
                            res = op.resultAction();
                            Console.WriteLine("Результат -> " + res);
                            break;
                        case "factorial":
                            if (flagDog == true)
                            {
                                n1 = Convert.ToInt32(boof1);
                                flagDog = false;
                            }
                            else
                            {
                                n1 = retNum(boof1, 'l');
                            }
                            op = new Operate(strAction, n1);
                            res = op.resultAction();
                            Console.WriteLine("Результат -> " + res);
                            break;             
                    }
                    flagAction = false;
                }
                else if (boof1[0] == 'a' && boof2[0] == 'a')
                {
                    int n1, n2;
                    n1 = retNum(boof1, 'a');
                    n2 = retNum(boof2, 'a');
                    op = new Operate(mas[n1 - 1].ToString(), mas[n2 - 1].ToString(), sing);
                    res = op.result();
                    Console.WriteLine("Результат -> " + res);
                }
                else if (boof1[0] == 'a')
                {
                    int n1;
                    n1 = retNum(boof1, 'a');
                    op = new Operate(mas[n1 - 1].ToString(), boof2, sing);
                    res = op.result();
                    Console.WriteLine("Результат -> " + res);
                }
                else if (boof2 !="" && boof2[0] == 'a')
                {
                    int n2;
                    n2 = retNum(boof2, 'a');
                    op = new Operate(boof1, mas[n2 - 1].ToString(), sing);
                    res = op.result();
                    Console.WriteLine("Результат -> " + res);
                }
                else if (boof1 != "" && boof2 != "" && sing != ' ')
                {
                    op = new Operate(boof1, boof2, sing);
                    res = op.result();
                    Console.WriteLine("Результат -> " + res);
                }
                if (flagScript == true)//если работаем со скриптом
                {
                    if (flagRead == true)
                    {
                        string line = "";
                        StreamReader file = new StreamReader(@"...\...\script.txt");
                        while ((line = file.ReadLine()) != null)
                        {
                            myList.Add(line);
                        }
                        file.Close();
                        flagRead = false;
                    }
                    while(count<myList.Count)
                    {
                        str = "";
                        boof1 = "";
                        boof2 = "";
                        sing = ' ';
                        flagDigit = true;
                        str = myList[count];
                        Console.WriteLine(str);
                        count++;
                        goto read;
                    }
                    flagScript = false;
                    flagRead = true;
                }
                str = "";
                boof1 = "";
                boof2 = "";
                sing = ' ';
                flagDigit = true;
                goto start;
            }
        }
        public static int retNum(string s, char c)//возвращает № сохраненного элемента значение после sin cos........
        {
            int n = 0;//возвращаемое значение
            try
            {
                string strSave = "";//строка элемента, который мы сохраняем
                int i = s.Length - 1;
                while (s[i] != c)
                {
                    strSave += s[i];
                    i--;
                }
                char[] ar = strSave.ToCharArray();
                Array.Reverse(ar);
                strSave = new String(ar);
                n = Convert.ToInt16(strSave);
            }
            catch (FormatException)
            {
                Console.WriteLine("Не верный ввод");
            }
            return n;
        }
    }
}
